package cn.yll.web.controller;

import cn.yll.api.user.request.UserExtendModifyRequest;
import cn.yll.api.user.request.UserPwdLoginRequest;
import cn.yll.api.user.request.UserRegisterRequest;
import cn.yll.api.user.response.UserBaseResponse;
import cn.yll.api.user.response.UserExtendResponse;
import cn.yll.api.user.service.RemoteUserExtendFeignService;
import cn.yll.api.user.service.RemoteUserFeignService;
import cn.yll.api.conf.UserAuthorize;
import cn.yll.api.util.JwtUserUtil;
import cn.yll.common.constant.MyConstants;
import cn.yll.common.exception.BsErrEnum;
import cn.yll.common.module.RestModel;
import cn.yll.api.util.RestUtil;
import cn.yll.common.utils.JwtTokenUtil;
import cn.yll.common.utils.RedisUtil;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.WebAsyncTask;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 用户相关接口
 * @author yangll
 */
@Slf4j
@RestController
@Api(tags = "用户相关接口")
@RequestMapping("user")
public class UserController extends BaseController {
    @Resource
    RemoteUserFeignService remoteUserFeignService;
    @Autowired
    RemoteUserExtendFeignService remoteUserExtendFeignService;
    @Autowired
    RedisUtil redisUtil;

    @GetMapping("testCallable")
    @ApiOperation(value = "异步获取callable", notes = "测试callable")
    public Callable<RestModel<UserExtendResponse>> testCallable(Long userId) {
        return () -> remoteUserExtendFeignService.getUserExtendByUserId(userId);
    }

    @GetMapping("testWebAsyncTask")
    @ApiOperation(value = "异步获取WebAsyncTask", notes = "测试WebAsyncTask")
    public WebAsyncTask<RestModel<UserExtendResponse>> testWebAsyncTask(Long userId) {
        return new WebAsyncTask<>(1000L, ()-> remoteUserExtendFeignService.getUserExtendByUserId(userId));
    }

    @GetMapping("testFuture")
    @ApiOperation(value = "异步获取Future", notes = "测试CompletableFuture")
    public RestModel<UserExtendResponse> testFuture(Long userId) throws ExecutionException, InterruptedException {
        CompletableFuture<RestModel<UserExtendResponse>> future = CompletableFuture.supplyAsync(() -> remoteUserExtendFeignService.getUserExtendByUserId(userId));
        return future.get();
    }

    @PostMapping("base/userRegister")
    @ApiOperation(value = "用户注册接口", notes = "所有参数必填, token是请求令牌，refresh_token令牌失效的刷新凭证")
    public RestModel<Map<String, String>> userRegister(@RequestBody UserRegisterRequest request) {
        RestModel<UserBaseResponse> restModel = remoteUserFeignService.register(request);
        if (RestUtil.isSuccess(restModel) && Objects.nonNull(restModel.getData())) {
            return RestUtil.sucess(JwtTokenUtil.createTokens(restModel.getData().getId()));
        }
        return RestUtil.rest(restModel.getCode(), restModel.getMessage(), null);
    }

    @PostMapping("pwdLogin")
    @ApiOperation(value = "用户密码登录接口", notes = "所有参数必填, token是请求令牌，refresh_token令牌失效的刷新凭证")
    public RestModel<Map<String, String>> pwdLogin(@RequestBody UserPwdLoginRequest request) {
        if (Objects.isNull(request) || StringUtils.isAnyBlank(request.getUserName(), request.getPwd())) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserBaseResponse> restModel = remoteUserFeignService.validUserPwd(request);
        if (RestUtil.isSuccess(restModel) && Objects.nonNull(restModel.getData())) {
            return RestUtil.sucess(JwtTokenUtil.createTokens(restModel.getData().getId()));
        }
        return RestUtil.error(BsErrEnum.PWD_ERROR);
    }

    @PostMapping("refreshToken")
    @ApiOperation(value = "令牌过期刷新接口", notes = "所有参数必填,返回新的token")
    public RestModel<String> refreshToken(@RequestBody String refreshToken) {
        if (StringUtils.isBlank(refreshToken)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        String userId = redisUtil.getV(refreshToken);
        if (StringUtils.isBlank(userId) || "0".equals(userId)) {
            return RestUtil.error(BsErrEnum.LOGIN_EXPIRE);
        }
        return RestUtil.sucess(JwtTokenUtil.createJwtToken(Long.valueOf(userId)));
    }

    @GetMapping("base/getById/{id}")
    @ApiOperation(value = "根据用户ID查询基本信息", notes = "Id必填")
    public RestModel<UserBaseResponse> getUserById(@PathVariable("id") Long userId) {
        if (Objects.isNull(userId)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserBaseResponse> restModel = remoteUserFeignService.getUserById(userId);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @GetMapping("base/getByUserName/{userName}")
    @ApiOperation(value = "根据用户名查询基本信息", notes = "登录用户名必填")
    public RestModel<UserBaseResponse> getByUserName(@PathVariable("userName") String userName) {
        if (StringUtils.isBlank(userName)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserBaseResponse> restModel = remoteUserFeignService.getByUserName(userName);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @GetMapping("base/getByPhone/{phone}")
    @ApiOperation(value = "根据手机号查询用户信息", notes = "手机号必填")
    public RestModel<UserBaseResponse> getByPhone(@PathVariable("phone") String phone) {
        if (StringUtils.isBlank(phone)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserBaseResponse> restModel = remoteUserFeignService.getByPhone(phone);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @PostMapping("extend/modify/userId")
    @ApiOperation(value = "更新用户扩展信息接口", notes = "用户ID必填")
    public RestModel<Boolean> modifyByUserId(@RequestBody UserExtendModifyRequest modifyRequest) {
        if (Objects.isNull(modifyRequest) || Objects.isNull(modifyRequest.getUserId())) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<Boolean> restModel = remoteUserExtendFeignService.modifyByUserId(modifyRequest);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @UserAuthorize
    @GetMapping("extend/loginUser")
    @ApiOperation(value = "查询当前登录用户扩展信息", notes = "")
    @ApiImplicitParam(name = MyConstants.TOKEN_KEY, value = "用户登录token", dataType = "string", paramType = "header", required = true)
    public RestModel<UserExtendResponse> getLoginUserExtend() {
        Long id = JwtUserUtil.getLoginUserId();
        RestModel<UserExtendResponse> restModel = remoteUserExtendFeignService.getUserExtendByUserId(id);
        return RestUtil.sucess(restModel.getData());
    }

    @GetMapping("extend/getById/{id}")
    @ApiOperation(value = "根据ID查询用户扩展信息", notes = "主键ID必填")
    public RestModel<UserExtendResponse> getUserExtendById(@PathVariable("id") Long id) {
        if (Objects.isNull(id)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserExtendResponse> restModel = remoteUserExtendFeignService.getUserExtendById(id);
        return RestUtil.sucess(restModel.getData());
    }

    @GetMapping("extend/getByUserId/{userId}")
    @ApiOperation(value = "根据用户ID查询扩展信息", notes = "userId必填")
    @SentinelResource(value = "resourceNameXXX", entryType = EntryType.IN)
    public RestModel<UserExtendResponse> getUserExtendByUserId(@PathVariable("userId") Long userId) throws InterruptedException {
        if (Objects.isNull(userId)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
//        Thread.sleep(1000L);
//        if (CommonUtil.nextInt(10) > 1) {
//            throw new RuntimeException();
//        }
        RestModel<UserExtendResponse> restModel = remoteUserExtendFeignService.getUserExtendByUserId(userId);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @GetMapping("extend/getByIdNo/{idNo}")
    @ApiOperation(value = "根据身份证号查询扩展信息", notes = "身份证号必填")
    public RestModel<UserExtendResponse> getByIdNo(@PathVariable("idNo") String idNo) {
        if (StringUtils.isBlank(idNo)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserExtendResponse> restModel = remoteUserExtendFeignService.getByIdNo(idNo);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

    @PostMapping("extend/getByEmail")
    @ApiOperation(value = "根据邮箱账号查询扩展信息", notes = "邮箱必填")
    public RestModel<UserExtendResponse> getByEmail(@RequestBody String email) {
        if (StringUtils.isBlank(email)) {
            return RestUtil.error(BsErrEnum.PARAM_EMPTY);
        }
        RestModel<UserExtendResponse> restModel = remoteUserExtendFeignService.getByEmail(email);
        if (!RestUtil.isSuccess(restModel)) {
            return RestUtil.error(BsErrEnum.RPC_ERROR);
        }
        return RestUtil.sucess(restModel.getData());
    }

}
